# 第9章 开发环境调优
# webpack开发效率插件
# webpack-dashboard
webpack-dashboard用来更好的展示打包信息。
npm i webpack-dashboard
const DashboardPlugin = require('webpack-dashboard/plgin');
module.exports = {
plugins: [
new DashboardPlugin();
]
}
2
3
4
5
6
7
还需要更改webpack的启动方式
// package.json
{
"script": {
"dev": "webpack-dashboard --webpack-dev-server"
}
}
2
3
4
5
6
# webpack-merge
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
module.exports = merge.smart(commonConfig, {
module: {
rules: [
{
test: /\.css$/
}
]
}
})
2
3
4
5
6
7
8
9
10
11
在合并module.rules的过程中会以test作为标识符,当发现有相同项出现时会以后面的规则覆盖前面的规则。
# speed-measure-webpack-plugin
SMP可以分析出webpack整个打包过程中在各个loader和plugin上耗费的时间。
npm i speed-measure-webpack-plugin
// webpack.config.js
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
entry: './app.js'
})
2
3
4
5
6
7
8
# size-plugin
size-plugin帮助我们监控资源体积的变化。
npm i size-plugin
const SizePlugin = require('size-plugin');
module.exports = {
plugins: [
new SizePlugin()
]
}
2
3
4
5
6
7
8
9
每次打包后size-plugin都会输出本次构建的资源体积以及与上次构建相比体积变化了多少。
# 模块热替换
最早调试代码都是改代码-刷新网页查看结果-再改代码。后来只要检测到代码改动就会自动重新构建,然后触发网页刷新。webpack在这个基础上又进一步,可以让代码在网页不刷新的前提下得到最新的改动,这就是模块热替换功能(Hot Module Replacement, HMR)。
# 开启HMR
webpack本身的命令行不支持HMR,项目要保证是基于webpack-dev-server或者webpack-dev-middle进行开发的。
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true
}
}
2
3
4
5
6
7
8
9
上面配置webpack会为每个模块绑定一个module.hot对象。这个对象包含了HMR的API。
调用HMR API有两种方式,一种是手动添加这部分代码;另一种是借助工具如react-hot-loader、vue-loader等。
// index.js
import {add} from 'util.js';
add(2, 3);
if(module.hot) {
module.hot.accept();
}
2
3
4
5
6
7
当现有模块发生变动时,HMR会使应用在当前浏览器环境下重新执行一遍index.js(包括依赖)的内容,但是页面本身不会刷新。
# HMR原理
在开启HMR的状态下进行开发,资源的体积会比原来的大很多,因为webpack为了实现HMR而注入了很多相关代码。
在本地开发环境下,浏览器是客户端,webpack-dev-server(WDS)相当于是我们的服务端。HMR的核心就是客户端从服务端拉取更新后的资源。
WDS与浏览器间维护了一个websocket,当本地资源发生变化时WDS会向浏览器推送更新时间,并带上这次构建的hash,让客户端与上次资产进行比对。通过hash的对比可以防止冗余更新的出现。因为很多时候源文件的更改并不一定代码构建结果的更改(比如添加了一个文件末尾空行)。
现在客户端已经知道新的构建结果和当前的有了差别,就会向WDS发起一个请求来获取更改文件的列表。通常这个请求的名字为[hash].hot-update.json。
// WDS向浏览器的返回值
{"h": "e388ddsjdfas", "c":{"main": true}}
2
需要更新的chunk为main,版本为e388ddsjdfas。这样客户端就可以再借助这些信息继续向WDS获取该chunk的增量更新。
// 增量接口
http://localhot:3000/dist/main.2410644c20694722f9ca.hot-update.js
// 返回值
webpackHotUpdate("main", {
(function(module, __webpack_exports__, __webpack_require__){
"use strict";
eval(...)
})
})
2
3
4
5
6
7
8
9
10
// index.js
if(module.hot) {
module.hot.decline();
module.hot.accept(['./util.js']);
}
2
3
4
5
module.hot.decline是将当前index.js的HMR关闭掉,后面一句是当util.js改变时依然可以启用HMR更新。